// $codepro.audit.disable booleanMethodNamingConvention
package people;

import infoholders.Invoice;

import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * The Nurse class; this represents the nurses in our system
 * 
 * @author Peter
 * 
 * @version $Revision: 1.0 $
 */
public class Nurse extends Person {
	// probably a list/collection/bag of patients instead -> THINK: handling
	// multiple patients
	/**
	 * Field current.
	 */
	private Patient current;

	/**
	 * Patient ID corresponding to the Patient table
	 */
	protected String currentPatientUsername;

	// will need to access DB here for patient list, synchronizing needed as
	// well
	/**
	 * Field patientDB.
	 */
	private Map<String, Patient> patientDB;

	// for searching the patient real name
	/**
	 * Field patientNameDB Holds patients real names and maps to respected
	 * username Real name formated: last name space first name
	 */
	private Map<String, List<String>> patientNameDB;

	/**
	 * Constructor that creates nurses and adds the nurse to the database
	 * 
	 * @param fName
	 * @param lName
	 */
	public Nurse(String fName, String lName) {
		super(fName, lName);
		setPatientDB(new HashMap<String, Patient>());
		setPatientNameDB(new HashMap<String, List<String>>());
		MYLOGGER.info("In Nurse constructor");
		setPersonType(UserType.NURSE);

		// store the object to the database
		// create();
	}

	/**
	 * A more verbose constructor for testing
	 * 
	 * @param fName
	 * @param lName
	 * @param username
	 * @param password
	 */
	public Nurse(String fName, String lName, String username, String password) {
		super(fName, lName);
		MYLOGGER.info("In Nurse constructor");

		this.setUserID(username);
		this.setUserPass(password);

		create();
	}

	/**
	 * Generic constructor for a Nurse
	 */
	public Nurse() {
		super();
		MYLOGGER.info("In Nurse constructor");
	}

	/**
	 * Getter for the username of the current patient
	 * 
	 * @return the username of the nurse's current patient
	 */
	public String getCurrentPatientUsername() {
		return currentPatientUsername;
	}

	/**
	 * Getter for the current patient
	 * 
	 * @return the nurse's current patient
	 */
	public Patient getCurrentPatient() {
		return getCurrent();
	}

	/**
	 * Setter for the username of the current patient
	 * 
	 * @param currentPatientUsername
	 *            the new patient username
	 */
	public void setCurrentPatientUsername(String currentPatientUsername) {
		/*
		 * // set the username in the database first String currentPatientUpdate
		 * = "UPDATE nurse SET patient = \"" + currentPatientUsername +
		 * "\" WHERE username='" + this.getUserID() + "'";
		 * 
		 * Database.executeUpdateQuery(currentPatientUpdate);
		 */
		this.currentPatientUsername = currentPatientUsername;
	}

	/**
	 * Creates a patient object service this patient
	 * 
	 * @param fName
	 *            - first name of patient
	 * @param lName
	 *            - last name of patient
	 * 
	 * @return a boolean that the patient is successfully created and stored
	 */
	public boolean createPatient(String fName, String lName) {
		if (fName == null)
			return false;
		if (lName == null)
			return false;
		String temp = lName + " " + fName;
		MYLOGGER.info("Nurse/Doctor is trying to add patient to system");

		final Patient someone = new Patient(fName, lName);
		// check if username is already in system; if so, keep looping and
		// prompting to change username

		// actually, this will be handled in Person

		// do later
		// while(!PatientDB.containsKey(uName)){
		// re-gen uName if auto-gen
		// else nurse is prompt
		// }
		// patientDB.put(someone.getUserID(), someone);
		// List<String> holder = patientNameDB.get(temp);
		// if(holder == null){
		// List<String> nameList = new LinkedList<String>();
		// nameList.add(someone.getUserID());
		// patientNameDB.put(temp, nameList);
		// }
		// else{
		// holder.add(someone.getUserID());
		// spatientNameDB.put(temp, holder);
		current = someone;
		// }
		return true;
	}

	/**
	 * Will delete the patient from the system if it exists, if
	 * patient/nurse/doctor does not know patient's username he/she will do a
	 * search first and find the correct patient to delete.
	 * 
	 * @param uName
	 *            - patient's username
	 * 
	 * @return a boolean where true signals that the patient was found and
	 *         deleted and false signals it did not exist
	 */
	public boolean deletePatient(String uName) {
		MYLOGGER.info("Nurse/Doctor is trying to remove patient from system");
		final Patient removed = getPatientDB().remove(uName);
		if (removed != null) {
			String temp = removed.getLastName() + " " + removed.getFirstName();
			List<String> tempholder = getPatientNameDB().get(temp);
			tempholder.remove(uName);
			MYLOGGER.info("Patient deleted from system");
			return true;
		}
		MYLOGGER.warning("Patient not found in system, abort deletion");
		return false;
	}

	/**
	 * Will search for the patient and service that patient
	 * 
	 * @param uName
	 *            - patient's username or real name
	 * 
	 * @return a list of patients (in case there were multiple people with same
	 *         name)
	 */
	public List<String> searchPatient(String uName, boolean isUserName) { // later
																			// will
																			// add
																			// for
																			// more
																			// flexibility
																			// like
																			// searching
																			// only
																			// by
																			// first
																			// name
		LinkedList<String> userNameHit = new LinkedList<String>();
		MYLOGGER.info("Nurse/Doctor is trying to search for patient in system");
		if (!isUserName) { // this is not a username (!!!) need to manually set
							// current patient
			// need to handle multiple instances (threading)
			List<String> tempName = getPatientNameDB().get(uName); // search the
																	// real
																	// name
																	// database
																	// for
																	// respected
																	// username
			if (tempName == null) {
				MYLOGGER.info("Patient not found in system");
				return new LinkedList<String>();
			} else {
				MYLOGGER.info("Patient(s) found in system");
				return tempName; // return the list
			}
		} else {
			// search and set equal to current
			setCurrent(getPatientDB().get(uName));
			userNameHit.add(uName);
			if (getCurrent() != null) {
				MYLOGGER.info("Patient found in system");
				return userNameHit;
			}
			MYLOGGER.warning("Patient not found in system");
			return new LinkedList<String>();
		}
	}

	/**
	 * Ideally a UI button, pulls up a section that will allow the nurse to edit
	 * patient details
	 */
	public void modifyPatient() {
		MYLOGGER.info("Nurse/Doctor is trying to modify current patient details");
		// pulls up patient details onto UI
	}

	/**
	 * Ideally a UI button, pulls up a section that will allow the nurse to see
	 * a list of appointments for the day/week
	 */
	public void viewAppointments() {
		MYLOGGER.info("Nurse/Doctor is viewing appointment page");
		// pulls up appointment page on UI
	}

	/**
	 * Ideally a UI button, pulls up a section that will allow the nurse to
	 * create a new appointment
	 * 
	 * @param month
	 *            - the name of the month EX.) "March"
	 * @param day
	 *            - the day of the month EX.) "30"
	 * @param year
	 *            - the year EX.) "2011"
	 * @param time
	 *            - appointment time EX.) "5:00PM"
	 * 
	 * @return a boolean where true signals that it has been create and false
	 *         signals that it conflicts and was not created
	 */
	public boolean createAppointment(String month, String day, String year,
			String time) {
		MYLOGGER.info("Nurse/Doctor is trying to create an appointment");
		// parameters goes into an appointment object
		return true;
	}

	/**
	 * Ideally a UI button, pulls up a section that will allow the nurse to
	 * create a treatment for the patient
	 * 
	 * 
	 * @return a boolean where true signals that a treatment has been created
	 *         and false signals that it was not created
	 */
	public boolean createTreatment() {
		MYLOGGER.info("Nurse/Doctor is trying to create a new treatment for patient");
		// pulls up UI for treatment details for current patient
		return true;
	}

	/**
	 * Overrides the default toString method
	 * 
	 * @return Nurse's name
	 */
	public String toString() {
		return "Nurse: " + this.getFirstName() + " " + this.getLastName();
	}

	/**
	 * Ideally a UI button, a button when pressed that bills the patient
	 */
	public void billPatient() {
		MYLOGGER.info("Nurse/Doctor is trying to bill patient");
		final PrinterJob printJob = PrinterJob.getPrinterJob();
		final Invoice myI = new Invoice();

		// final InvoiceView v = new InvoiceView(myI);
		// printJob.setPrintable(v);
		if (printJob.printDialog()) { // $codepro.audit.disable
										// nullPointerDereference
			try {
				printJob.print();
			} catch (PrinterException pe) {
				System.out.println("Error printing: " + pe);
			}
		}
	}

	/**
	 * Adds this Nurse object into the database
	 */
	public void create() {
		// super.create();
	}

	public void setPatientDB(Map<String, Patient> patientDB) {
		this.patientDB = patientDB;
	}

	public Map<String, Patient> getPatientDB() {
		return patientDB;
	}

	public void setCurrent(Patient current) {
		this.current = current;
	}

	public Patient getCurrent() {
		return current;
	}

	public void setPatientNameDB(Map<String, List<String>> patientNameDB) {
		this.patientNameDB = patientNameDB;
	}

	public Map<String, List<String>> getPatientNameDB() {
		return patientNameDB;
	}

}
